/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hoaptt.model;

import com.hoaptt.helper.Coordinate;
import com.hoaptt.helper.ValidateSwapPiece;
import com.hoaptt.pieces.Advisor;
import com.hoaptt.pieces.Cannon;
import com.hoaptt.pieces.Chariot;
import com.hoaptt.pieces.Default;
import com.hoaptt.pieces.Elephant;
import com.hoaptt.pieces.General;
import com.hoaptt.pieces.Horse;
import com.hoaptt.pieces.Piece;
import com.hoaptt.pieces.Soldier;
import java.util.ArrayList;

/**
 *
 * @author ThuHoa
 */
public class Board {

    public static int COL = 9;
    public static int ROW = 8;
    private Piece[][] pieces;
    private ArrayList<Piece[][]> savedState;

//    public enum NamePiece {
//        advisor, cannon, chariot, default1, elephant, general, horse, solider
//    }
    public Board() {
        pieces = new Piece[ROW + 1][COL + 1];
        savedState = new ArrayList<Piece[][]>();

        // default is ... Default
        for (int i = 0; i <= ROW; i++) {
            for (int j = 0; j <= COL; j++) {
                pieces[i][j] = new Default(Piece.PLAYER.A);
            }
        }

        //// building started board

        // player A
        pieces[0][0] = new Chariot(Piece.PLAYER.A);
        pieces[8][0] = new Chariot(Piece.PLAYER.A);
        pieces[1][0] = new Horse(Piece.PLAYER.A);
        pieces[7][0] = new Horse(Piece.PLAYER.A);
        pieces[2][0] = new Elephant(Piece.PLAYER.A);
        pieces[6][0] = new Elephant(Piece.PLAYER.A);
        pieces[3][0] = new Advisor(Piece.PLAYER.A);
        pieces[5][0] = new Advisor(Piece.PLAYER.A);
        pieces[4][0] = new General(Piece.PLAYER.A);
        pieces[1][2] = new Cannon(Piece.PLAYER.A);
        pieces[7][2] = new Cannon(Piece.PLAYER.A);
        pieces[0][3] = new Soldier(Piece.PLAYER.A);
        pieces[2][3] = new Soldier(Piece.PLAYER.A);
        pieces[4][3] = new Soldier(Piece.PLAYER.A);
        pieces[6][3] = new Soldier(Piece.PLAYER.A);
        pieces[8][3] = new Soldier(Piece.PLAYER.A);

        // player B
        pieces[0][9] = new Chariot(Piece.PLAYER.B);
        pieces[8][9] = new Chariot(Piece.PLAYER.B);
        pieces[1][9] = new Horse(Piece.PLAYER.B);
        pieces[7][9] = new Horse(Piece.PLAYER.B);
        pieces[2][9] = new Elephant(Piece.PLAYER.B);
        pieces[6][9] = new Elephant(Piece.PLAYER.B);
        pieces[3][9] = new Advisor(Piece.PLAYER.B);
        pieces[5][9] = new Advisor(Piece.PLAYER.B);
        pieces[4][9] = new General(Piece.PLAYER.B);
        pieces[1][7] = new Cannon(Piece.PLAYER.B);
        pieces[7][7] = new Cannon(Piece.PLAYER.B);
        pieces[0][6] = new Soldier(Piece.PLAYER.B);
        pieces[2][6] = new Soldier(Piece.PLAYER.B);
        pieces[4][6] = new Soldier(Piece.PLAYER.B);
        pieces[6][6] = new Soldier(Piece.PLAYER.B);
        pieces[8][6] = new Soldier(Piece.PLAYER.B);
    }

    public int getCol() {
        return COL;
    }

    public void setCol(int col) {
        this.COL = col;
    }

    public Piece[][] getPieces() {
        return pieces;
    }

    public void setPieces(Piece[][] pieces) {
        this.pieces = pieces;
    }

    public int getRow() {
        return ROW;
    }

    public void setRow(int row) {
        this.ROW = row;
    }

    public ArrayList<Piece[][]> getSavedState() {
        return savedState;
    }

    public void setSavedState(ArrayList<Piece[][]> savedState) {
        this.savedState = savedState;
    }

    public Piece getPiece(int i, int j) {
        return pieces[i][j];
    }

    // move two button (eat)
    /**
     * this method to check valid when piece at location x1 va y1 can eat piece at location x2 and y2
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     */
    void move(int x1, int y1, int x2, int y2) {
        // same player. cannot eat
        if (pieces[x1][y1].player == pieces[x2][y2].player) {
            return;
        }
        if (pieces[x1][y1] == null || pieces[x2][y2] == null) {
            return;
        }
        // different player
        // swap
        //chariot
        if (pieces[x1][y1].getAlias() == Piece.NAMEPIECE.chariot) {
            ArrayList<Coordinate> ar = (new Chariot(getAtLoc(x1, y1).getPlayer())).generateMove(this, new Coordinate(x1, y1));
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, x2, y2)) {
                    pieces[x2][y2].setPlayer(pieces[x1][y1].getPlayer());
                    pieces[x2][y2].setName(pieces[x1][y1].getName());
                    pieces[x2][y2].setAlias(pieces[x1][y1].getAlias());
                    pieces[x1][y1].setName("default");
                    pieces[x1][y1].setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }
        //solider
        if (pieces[x1][y1].getAlias() == Piece.NAMEPIECE.solider) {
            ArrayList<Coordinate> ar = (new Soldier(getAtLoc(x1, y1).getPlayer())).generateMove(this, new Coordinate(x1, y1));
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, x2, y2)) {
                    pieces[x2][y2].setPlayer(pieces[x1][y1].getPlayer());
                    pieces[x2][y2].setName(pieces[x1][y1].getName());
                    pieces[x2][y2].setAlias(pieces[x1][y1].getAlias());
                    pieces[x1][y1].setName("default");
                    pieces[x1][y1].setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }

        //horse
        if (pieces[x1][y1].getAlias() == Piece.NAMEPIECE.horse) {
            ArrayList<Coordinate> ar = (new Horse(getAtLoc(x1, y1).getPlayer())).generateMove(this, new Coordinate(x1, y1));
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, x2, y2)) {
                    pieces[x2][y2].setPlayer(pieces[x1][y1].getPlayer());
                    pieces[x2][y2].setName(pieces[x1][y1].getName());
                    pieces[x2][y2].setAlias(pieces[x1][y1].getAlias());
                    pieces[x1][y1].setName("default");
                    pieces[x1][y1].setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }

        //elephant
        if (pieces[x1][y1].getAlias() == Piece.NAMEPIECE.elephant) {
            ArrayList<Coordinate> ar = (new Elephant(getAtLoc(x1, y1).getPlayer())).generateMove(this, new Coordinate(x1, y1));
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, x2, y2)) {
                    pieces[x2][y2].setPlayer(pieces[x1][y1].getPlayer());
                    pieces[x2][y2].setName(pieces[x1][y1].getName());
                    pieces[x2][y2].setAlias(pieces[x1][y1].getAlias());
                    pieces[x1][y1].setName("default");
                    pieces[x1][y1].setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }

        //advisor
         if (pieces[x1][y1].getAlias() == Piece.NAMEPIECE.advisor) {
            ArrayList<Coordinate> ar = (new Advisor(getAtLoc(x1, y1).getPlayer())).generateMove(this, new Coordinate(x1, y1));
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, x2, y2)) {
                    pieces[x2][y2].setPlayer(pieces[x1][y1].getPlayer());
                    pieces[x2][y2].setName(pieces[x1][y1].getName());
                    pieces[x2][y2].setAlias(pieces[x1][y1].getAlias());
                    pieces[x1][y1].setName("default");
                    pieces[x1][y1].setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }
        //general
         if (pieces[x1][y1].getAlias() == Piece.NAMEPIECE.general) {
            ArrayList<Coordinate> ar = (new General(getAtLoc(x1, y1).getPlayer())).generateMove(this, new Coordinate(x1, y1));
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, x2, y2)) {
                    pieces[x2][y2].setPlayer(pieces[x1][y1].getPlayer());
                    pieces[x2][y2].setName(pieces[x1][y1].getName());
                    pieces[x2][y2].setAlias(pieces[x1][y1].getAlias());
                    pieces[x1][y1].setName("default");
                    pieces[x1][y1].setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }



//        pieces[x2][y2].setPlayer(pieces[x1][y1].getPlayer());
//        pieces[x2][y2].setName(pieces[x1][y1].getName());
//        pieces[x2][y2].setAlias(pieces[x1][y1].getAlias());
//        System.out.println("Loca 1:" + x1 + "/t" + y1);
//        System.out.println("Loca 2:" + x2 + "/t" + y2);
//        pieces[x1][y1].setName("default");
//        pieces[x1][y1].setAlias(Piece.NAMEPIECE.default1);
//
//        System.out.println("testting:");
//        System.out.println(pieces[x1][y1].getName());
//        System.out.println(pieces[x2][y2].getName());


    }

    /**
     *
     * this method to move piece from loc1 to loc2
     * @param loc1
     * @param loc2
     */
    void move(Coordinate loc1, Coordinate loc2) {
        // if same player
        // if first click on defaut button
        System.out.println("Alias: " + getAtLoc(loc1).getAlias());
        if (getAtLoc(loc1).getName().equals("defaut")) {
            System.out.println("Loc1 is default:");
            return;
        }
        // if user don't click on panel
        if (getAtLoc(loc1) == null || getAtLoc(loc2) == null) {
            System.out.println("null");
            return;
        }
        //  if button valid
//         getAtLoc(loc2).setPlayer(getAtLoc(loc1).getPlayer());
//            getAtLoc(loc2).setName(getAtLoc(loc1).getName());
//            getAtLoc(loc1).setName("default");
        // Advisor
        if (getAtLoc(loc1).getAlias() == Piece.NAMEPIECE.advisor) {
            // if alias = advisor, create new advisor to excute method generateMove
            // after move, type of piece at loc1 until is Advisor and type of piece at loc2 until Default
            ArrayList<Coordinate> ar = (new Advisor(getAtLoc(loc1).getPlayer())).generateMove(this, loc1);
            if (ar != null) {
                // check loc2 is the move valid
                if (checkArray(ar, loc2)) {
                    getAtLoc(loc2).setAlias(Piece.NAMEPIECE.advisor);
                    getAtLoc(loc2).setPlayer(getAtLoc(loc1).getPlayer());
                    getAtLoc(loc2).setName(getAtLoc(loc1).getName());
                    getAtLoc(loc1).setName("default");
                    getAtLoc(loc1).setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }

        //Cannon
        if (getAtLoc(loc1).getAlias() == Piece.NAMEPIECE.cannon) {
            ArrayList<Coordinate> ar = (new Cannon(getAtLoc(loc1).getPlayer())).generateMove(this, loc1);
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, loc2)) {
                    getAtLoc(loc2).setAlias(Piece.NAMEPIECE.cannon);
                    getAtLoc(loc2).setPlayer(getAtLoc(loc1).getPlayer());
                    getAtLoc(loc2).setName(getAtLoc(loc1).getName());
                    getAtLoc(loc1).setName("default");
                    getAtLoc(loc1).setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }

        //Chariot
        if (getAtLoc(loc1).getAlias() == Piece.NAMEPIECE.chariot) {
            ArrayList<Coordinate> ar = (new Cannon(getAtLoc(loc1).getPlayer())).generateMove(this, loc1);
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, loc2)) {
                    getAtLoc(loc2).setAlias(Piece.NAMEPIECE.chariot);
                    getAtLoc(loc2).setPlayer(getAtLoc(loc1).getPlayer());
                    getAtLoc(loc2).setName(getAtLoc(loc1).getName());
                    getAtLoc(loc1).setName("default");
                    getAtLoc(loc1).setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }

        //Elephant
        if (getAtLoc(loc1).getAlias() == Piece.NAMEPIECE.elephant) {
            ArrayList<Coordinate> ar = (new Elephant(getAtLoc(loc1).getPlayer())).generateMove(this, loc1);
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, loc2)) {
                    getAtLoc(loc2).setAlias(Piece.NAMEPIECE.elephant);
                    getAtLoc(loc2).setPlayer(getAtLoc(loc1).getPlayer());
                    getAtLoc(loc2).setName(getAtLoc(loc1).getName());
                    getAtLoc(loc1).setName("default");
                    getAtLoc(loc1).setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }

        //general
        if (getAtLoc(loc1).getAlias() == Piece.NAMEPIECE.general) {
            ArrayList<Coordinate> ar = (new General(getAtLoc(loc1).getPlayer())).generateMove(this, loc1);
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, loc2)) {
                    getAtLoc(loc2).setAlias(Piece.NAMEPIECE.general);
                    getAtLoc(loc2).setPlayer(getAtLoc(loc1).getPlayer());
                    getAtLoc(loc2).setName(getAtLoc(loc1).getName());
                    getAtLoc(loc1).setName("default");
                    getAtLoc(loc1).setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }

        // horse
        if (getAtLoc(loc1).getAlias() == Piece.NAMEPIECE.horse) {
            ArrayList<Coordinate> ar = (new Horse(getAtLoc(loc1).getPlayer())).generateMove(this, loc1);
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, loc2)) {
                    getAtLoc(loc2).setAlias(Piece.NAMEPIECE.horse);
                    getAtLoc(loc2).setPlayer(getAtLoc(loc1).getPlayer());
                    getAtLoc(loc2).setName(getAtLoc(loc1).getName());
                    getAtLoc(loc1).setName("default");
                    getAtLoc(loc1).setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }

        //solider
        if (getAtLoc(loc1).getAlias() == Piece.NAMEPIECE.solider) {
            ArrayList<Coordinate> ar = (new Soldier(getAtLoc(loc1).getPlayer())).generateMove(this, loc1);
            if (ar != null) {
                System.out.println("Size array: " + ar.size());
                // check loc2 is the move valid
                if (checkArray(ar, loc2)) {
                    getAtLoc(loc2).setAlias(Piece.NAMEPIECE.solider);
                    getAtLoc(loc2).setPlayer(getAtLoc(loc1).getPlayer());
                    getAtLoc(loc2).setName(getAtLoc(loc1).getName());
                    getAtLoc(loc1).setName("default");
                    getAtLoc(loc1).setAlias(Piece.NAMEPIECE.default1);
                }
            }
        }
    }

    public Piece getAtLoc(Coordinate coo) {
        if ((coo.getRow() >= 0 && coo.getRow() <= 8) && (coo.getCol() >= 0 && coo.getCol() <= 9)) {
            return pieces[coo.getRow()][coo.getCol()];
        }
        return null;
    }

    public Piece getAtLoc(int x, int y) {
        Coordinate coo = new Coordinate(x, y);
        if ((coo.getRow() >= 0 && coo.getRow() <= 8) && (coo.getCol() >= 0 && coo.getCol() <= 9)) {
            return pieces[coo.getRow()][coo.getCol()];
        }
        return null;
    }

    private boolean checkArray(ArrayList<Coordinate> ar, Coordinate loc) {
        for (Coordinate location : ar) {
            if (location.getRow() == loc.getRow() && location.getCol() == loc.getCol()) {
                return true;
            }
        }
        return false;
    }

    private boolean checkArray(ArrayList<Coordinate> ar, int x, int y) {
        Coordinate loc = new Coordinate(x, y);
        for (Coordinate location : ar) {
            if (location.getRow() == loc.getRow() && location.getCol() == loc.getCol()) {
                return true;
            }
        }
        return false;
    }
}
